package Scuttlebutt;

import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import java.awt.Component;
import java.io.*;
import java.awt.Color;
import java.util.*;
import glue.ftp.*;

class FolderNode extends SortableNode
{
	String link = null;
	FolderNode(Object obj, String path)
    {
    	super(obj, path);
    }
    
    public void setLink(String link){
	    this.link = link;
    }
    
    public String getLink(){
	    return link;
    }
    
    
    public FolderNode addDirectory(Scuttlebutt parent, String dirName){
		File dir = new File(getNodePath() + File.separatorChar + dirName);
		dir.mkdir();
		FolderNode node = null;
		String path = null;
		if(getNodePath().length() == 0){
			path = new String("");
		}else{
			path = new String(getNodePath() + File.separatorChar + dir.getName());
		}
		node = new FolderNode(dir.getName(), path);
		String remote_path = null;
		
		if(getRemoteDirectory().compareToIgnoreCase(parent.getRemoteHomeDirectory()) == 0){
			remote_path = new String("");
			node.setRemoteDirectory("");
		}else{
			if(getRemoteDirectory().length() == 0){
				remote_path = toString();
				node.setRemoteDirectory(toString());
			}else{
				remote_path = new String(getRemoteDirectory() + File.separatorChar + toString());
				node.setRemoteDirectory(remote_path);
			}
		}
		
//		add(node);
		int count = getChildCount();
		if(count == 0){
			add(node);
		}else{
			insert(node, count);
		}
	
		try{
			parent.getFTP().setDirectory(parent.getRemoteHomeDirectory());
			if(node.getRemoteDirectory().length() > 0){
				parent.getFTP().setDirectory(node.getRemoteDirectory());
			}
			parent.getFTP().makeDirectory(dirName);	
			node.setUploaded(parent.isConnected());
		}catch(IOException e){
			System.err.println("CreateDir IOE: " + e.getMessage());
		}catch(FtpException i){
			System.err.println("CreateDir ftp.FtpException: " + i.getMessage());
		}
		
		parent.updateTree();
		parent.saveProject();
		
		return node;
    }
    
    public URLNode addURLNode(String label, String url){
	    System.out.println("addURLNode label:" + label);
	    URLNode node = new URLNode(label, url);
	    setURL(true);
		int count = getChildCount();
		if(count == 0){
			add(node);
		}else{
			insert(node, count);
		}
	    return node;
    }
    
    public SortableNode addFile(Scuttlebutt parent, String fileName) throws IOException{
	    return addFile(parent, fileName, false);
    }
    
	public SortableNode addFile(Scuttlebutt parent, String fileName, boolean state) throws IOException{
		File file = new File(getNodePath() + File.separatorChar + fileName);
		if(!file.exists()){
			file.createNewFile();
		}
		SortableNode node = new SortableNode(file.getName(), file.getPath());
		node.setUploaded(state);
	
		String remote_dir = null;
		if(getRemoteDirectory().compareToIgnoreCase(parent.getRemoteHomeDirectory()) == 0){
			remote_dir = parent.getRemoteHomeDirectory();
		}else if(getRemoteDirectory().length() == 0){
			remote_dir = new String(toString());
		}else{
			remote_dir = new String(getRemoteDirectory() + File.separatorChar + toString());
		}
		
		node.setRemoteDirectory(remote_dir);
		
		int count = getChildCount();
		if(count == 0){
			add(node);
		}else{
			insert(node, count);
		}
		
		parent.updateTree();
		parent.saveProject();
		
		return node;
	}
    
    
    public void move(Scuttlebutt parent, FolderNode dest){
        File oldPath = new File(getNodePath());
	    File path = new File(new String(dest.getNodePath() + File.separatorChar + toString()));
		String oldRemoteDirectory = getRemoteDirectory();
		String newRemoteDirectory = new String(new String((dest.getRemoteDirectory().length() > 0)? new String(dest.getRemoteDirectory() + File.separatorChar): "") + dest.toString());
		
		if(!path.exists()){
			FolderNode temp = dest.addDirectory(parent, toString());
			recurseChildren(parent, this, temp);
		}else{
			FolderNode node = (FolderNode)parent.getProject().SearchTree((Object)parent.getRootNode(), path.getPath());
			recurseChildren(parent, this, node);
		}
		
		try{
//			String remote = new String(new String((getRemoteDirectory().length() > 0)? new String(getRemoteDirectory() + File.separatorChar): "") + toString());
//			System.out.println("remove directory:" + getRemote());
			parent.getFTP().setDirectory(parent.getRemoteHomeDirectory());
			parent.getFTP().removeDirectory(getRemote());
		}catch(java.io.IOException e){
			System.out.println(e);
		}catch(FtpException f){
			System.out.println("Failed to delete folder:" + f);
		}
		
	
		File f = new File(getNodePath());
		f.delete();
		removeFromParent();
		
		parent.updateTree();	
    }
    
    private void recurseChildren(Scuttlebutt parent, FolderNode source, FolderNode dest){
	    System.out.println("dest:" + dest.getNodePath());
		for (Enumeration en = source.children() ; en.hasMoreElements() ;) {
			Object o = en.nextElement();
			System.out.println("Child:" + o.toString());
			if (o instanceof FolderNode ) {
				FolderNode folder = (FolderNode)o;
				FolderNode temp = dest.addDirectory(parent, folder.toString());
				recurseChildren(parent, folder, temp);
	
				String remote = new String(new String((folder.getRemoteDirectory().length() > 0)?new String(folder.getRemoteDirectory() + File.separatorChar):"") + folder.toString());
				try{
					System.out.println("deleting..." + remote);
					parent.getFTP().removeDirectory(remote);
				}catch(java.io.IOException e){
					System.err.println(e);
				}catch(FtpException f){
					System.err.println("Failed to delete folder:" + f);
				}
				
				File f = new File(folder.getNodePath());
				f.delete();
				folder.removeFromParent();
				
			}else if (o instanceof SortableNode ){
				SortableNode local = (SortableNode)o;
//				System.out.println("move SortableNode:" + local.toString());
				try{
					File f = new File(new String(local.getNodePath()));
					File nFile = new File(new String(dest.getNodePath() + File.separatorChar + f.getName()));
					if(nFile.exists()){
						if(JOptionPane.showConfirmDialog(null, new String("You are about to delete:\n" + nFile.getPath() + "\n" +"This operation cannot be undone. Do you wish to continue?" ), "Warning", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION){
							return;
						}else{
							SortableNode node = (SortableNode)parent.getProject().SearchTree((Object)parent.getRootNode(), nFile.getPath());
							node.removeFromParent();
							nFile.delete();
						}
					}
			 	   	parent.getProject().removeOpened(local.getNodePath());
			 	  	String remote = null;
			 	  	
			 	  	remote = (dest.getRemoteDirectory().compareToIgnoreCase("/") == 0)? "" :new String(new String((dest.getRemoteDirectory().length() > 0)?dest.getRemoteDirectory() + File.separatorChar: "") + dest.toString());
			 	  	try{
						parent.getFTP().setDirectory(parent.getRemoteHomeDirectory());
						parent.getFTP().fileRename(local.getRemoteDirectory() + File.separatorChar + local.toString(), remote + File.separatorChar + local.toString());
					}catch(java.io.IOException e){
						System.err.println(e);
					}catch(FtpException fe){
						System.err.println("Failed to move file:" + fe);
					}
		 			local.updateLinks(parent, f, nFile, remote);
					f.renameTo(nFile);
					SortableNode node = dest.addFile(parent, local.toString(), true);
					node.filesList.addAll(local.filesList);
				}catch(IOException e){
					System.out.println(e);
				}
			}else if (o instanceof URLNode ){
				URLNode u = (URLNode)o;
				System.out.println("url " + u.toString());
				dest.addURLNode(u.toString(), u.getURL());
				u.removeFromParent();
				parent.updateTree();
				parent.saveProject();
				
			}else{
				System.out.println("error. none of the above");
			}
		}
    }
}

class URLNode extends DefaultMutableTreeNode
{
	String URL = null;
	URLNode(Object obj, String URL)
    {
    	super(obj);
    	this.URL = URL;
    	setAllowsChildren(false);
    }
    
    public String getURL(){
	    return URL;
    }
}

public class NodeRenderer extends DefaultTreeCellRenderer 
{
    public Component getTreeCellRendererComponent(
                        JTree tree,
                        Object value,
                        boolean sel,
                        boolean expanded,
                        boolean leaf,
                        int row,
                        boolean hasFocus) 
	{

		super.getTreeCellRendererComponent(
                        tree, value, sel,
                        expanded, leaf, row,
                        hasFocus);
                        
        if (value instanceof FolderNode ) {
            if ( expanded ) {
                setIcon(openIcon);
            }
            else {
                setIcon(closedIcon);
			}        
        } 
        
       
	    if(value instanceof URLNode ) {
	        setForeground(Color.BLUE);
        }else{
	        if(((SortableNode)value).isUploaded()){
	        	setForeground(Color.BLACK);
	        }else{
	        	setForeground(Color.RED);
	        }
		}
        	
		return this;
	}
}

